<template>
  <view class="registe__form-comp">
    <!-- 进度条 -->
    <Steps
      :steps="steps"
      :cur="step"
      class="registe__form-comp-step"
      @change="handleStepChange"
    />
    <!-- 三个面板 -->
    <Transition
      :show="step === 'mobile'"
      :mode-class="[`slide-${switchDirection}`]"
      :duration="150"
    >
      <view v-if="step === 'mobile'" class="registe__form-comp-panel">
        <!-- 验证手机 -->
        <view class="registe__form-comp-wrap">
          <input
            v-model="mobile"
            type="number"
            placeholder="请输入手机号码"
            placeholder-class="registe__form-comp-input-placeholder"
            :class="{
              'registe__form-comp-input': true,
              'has-error': error.mobile,
            }"
            @focus="clearError('mobile')"
          />
          <view class="registe__form-comp-error-text">{{ error.mobile }}</view>
        </view>
        <button
          lang="zh_CN"
          :class="['registe__form-comp-btn', { disabled: !sendMsgEnabled }]"
          :disabled="!sendMsgEnabled"
          @click="sendMsg"
        >
          {{ sendMsgText }}
        </button>
      </view>
    </Transition>
    <Transition
      :show="step === 'verification'"
      :mode-class="[`slide-${switchDirection}`]"
      :duration="150"
    >
      <view v-if="step === 'verification'" class="registe__form-comp-panel">
        <!-- 验证验证码 -->
        <view class="registe__form-comp-verify-confirm">
          <view>本次操作需要短信确认，</view>
          <view>
            验证码已经发送至您的手机
            <text class="registe__form-comp-verify-confirm-num">
              {{ hideMobile }}
            </text>
          </view>
        </view>
        <VerificationInput
          type="bottom"
          autoFocus
          :maxlength="6"
          @input="handleVerifyChange"
        />
      </view>
    </Transition>
    <Transition
      :show="step === 'password'"
      :mode-class="[`slide-${switchDirection}`]"
      :duration="150"
    >
      <view class="registe__form-comp-panel">
        <view class="registe__form-comp-wrap">
          <input
            v-model="password"
            type="password"
            placeholder="请输入登录密码"
            placeholder-class="registe__form-comp-input-placeholder"
            :class="{
              'registe__form-comp-input': true,
              'has-error': error.password,
              success: checkStatus.password,
            }"
            @focus="clearError('password')"
            @blur="checkPassword('first')"
          />
          <view class="registe__form-comp-error-text">
            {{ error.password }}
          </view>
        </view>
        <view class="registe__form-comp-wrap">
          <input
            v-model="confirmPassword"
            type="password"
            placeholder="请再次输入登录密码"
            placeholder-class="registe__form-comp-input-placeholder"
            :class="{
              'registe__form-comp-input': true,
              'has-error': error.confirmPassword,
              success: checkStatus.confirmPassword,
            }"
            @focus="clearError('confirmPassword')"
            @blur="checkPassword('second')"
          />
          <view class="registe__form-comp-error-text">
            {{ error.confirmPassword }}
          </view>
        </view>
        <button lang="zh_CN" class="registe__form-comp-btn" @click="doRegiste">
          确认
        </button>
      </view>
    </Transition>
  </view>
</template>

<script>
import VerificationInput from '@/components/verify-code/index.vue';
import Transition from '@/components/Transition';
import Steps from './Steps';
import { mapGetters } from 'vuex';

export default {
  components: {
    VerificationInput,
    Steps,
    Transition,
  },

  props: {},

  data() {
    return {
      steps: [
        { name: '手机号', sign: 'mobile' },
        { name: '验证短信', sign: 'verification' },
        { name: '设置登录密码', sign: 'password' },
      ],
      step: 'mobile',
      mobile: '',
      verification: '',
      password: '',
      confirmPassword: '',
      switchDirection: 'right', // 切换动画方向
      sendMsgText: '发送验证码', // 发送验证码按钮文案
      sendMsgEnabled: true,
      error: {
        mobile: '',
        password: '',
        password: '',
        confirmPassword: '',
      },
      checkStatus: {
        // 密码输入状态
        password: false,
        confirmPassword: false,
      },
    };
  },

  computed: {
    ...mapGetters(['redirect']),
    hideMobile() {
      return this.mobile
        .toString()
        .replace(/(\d{3})(\d{4})(\d{4})/, '$1****$3');
    },
  },

  methods: {
    clearError(name = '') {
      this.error[name] = '';
    },

    // 验证码改变响应函数
    handleVerifyChange(value) {
      if (value) this.verification = value;
      // 输入完毕开始验证短信验证码
      if (value.length === 6) this.valideCode();
    },

    // 当前步骤改变响应函数
    handleStepChange(step) {
      const { name, direction = 'right' } = step;
      if (name) {
        this.switchDirection = direction;
        // 延迟切换等待transition改变
        setTimeout(() => {
          this.step = name;
        }, 200);
      }
    },

    // 检查密码输入
    checkPassword(sign) {
      if (sign === 'first') {
        const passwordReg = /^[0-9A-Za-z_@]{6,30}$/;
        if (!this.password || !passwordReg.test(this.password)) {
          this.checkStatus.password = false;
          // this.error.password = '请输入6-30位字母或者数字的密码';
        } else {
          this.checkStatus.password = true;
        }
      } else if (sign === 'second') {
        if (!this.confirmPassword || this.password !== this.confirmPassword) {
          this.checkStatus.confirmPassword = false;
          // this.error.confirmPassword = '两次密码输入不一致';
        } else {
          this.checkStatus.confirmPassword = true;
        }
      }
    },

    sendMsg() {
      const mobileReg = /^1\d{10}$/;
      if (!this.mobile) {
        this.error.mobile = '请输入手机号码';
        return;
      }
      if (!mobileReg.test(this.mobile)) {
        this.error.mobile = '手机号码格式错误';
        return;
      }
      this.$http({
        method: 'POST',
        url: '/api/front/user/send_verify',
        data: {
          usage: 'registe',
          mobile: this.mobile,
        },
        skipToast: false,
        showLoading: true,
        errorText: '发送短信失败，请重新尝试',
      }).then((res) => {
        if (res.ok) {
          // 验证成功，直接前往下一步
          this.step = 'verification';
          this.sendMsgTimes = 60;
          this.sendMsgText = `${this.sendMsgTimes}s后重新获取`;
          this.sendMsgEnabled = false;
          this.sendMsgTimer = setInterval(() => {
            this.sendMsgTimes = this.sendMsgTimes - 1;
            this.sendMsgText = `${this.sendMsgTimes}s后重新获取`;
            if (this.sendMsgTimes <= 0) {
              clearInterval(this.sendMsgTimer);
              this.sendMsgText = '重新获取验证码';
              this.sendMsgEnabled = true;
              return;
            }
          }, 1000);
        } else {
          uni.showToast({ title: res.msg || '服务器繁忙', icon: 'none' });
        }
      });
    },

    // 验证验证码
    valideCode() {
      const verifyReg = /^[0-9]{6}$/;
      if (!this.verification || !verifyReg.test(this.verification)) {
        uni.showToast({ title: '请输入6位验证码', icon: 'none' });
        return;
      }
      this.$http({
        method: 'POST',
        url: '/api/front/user/check_verify',
        data: {
          mobile: this.mobile,
          verification: this.verification,
        },
        skipToast: false,
        showLoading: true,
        errorText: '验证短信出错了，请重新尝试',
      }).then((res) => {
        if (res.ok) {
          // 验证成功，直接前往下一步
          this.step = 'password';
        } else {
          if (res.goback) {
            this.step = 'mobile';
          }
          uni.showToast({ title: res.msg || '服务器繁忙', icon: 'none' });
        }
      });
    },

    doRegiste() {
      // 校验密码
      const passwordReg = /^[0-9A-Za-z_@]{6,30}$/;
      if (!this.password || !passwordReg.test(this.password)) {
        this.error.password = '请输入6-30位字母或者数字的密码';
        return;
      }
      if (this.password !== this.confirmPassword) {
        this.error.confirmPassword = '两次密码输入不一致';
        return;
      }
      // 开始注册
      this.$http({
        method: 'POST',
        url: '/api/front/user/registe',
        data: {
          wey: 'mobile',
          mobile: this.mobile,
          verification: this.verification,
          password: this.password,
        },
        skipToast: false,
        errorText: '注册失败，请重新尝试',
      }).then((res) => {
        if (res.ok) {
          // 注册成功
          this.$store.commit('showSuccessTips', '注册成功');
          this.$store.commit('login', {
            cache: true,
            token: res.token,
            userInfo: res.userInfo,
          });
          const {
            type = 'navigateTo',
            url = encodeURIComponent('/pages/index/index'),
          } = this.redirect;
          uni[type]({ url: decodeURIComponent(url) });
        } else if (!res.ok && res.error) {
          uni.showModal({
            title: '温馨提示',
            content: Object.keys(res.error)
              .map((item) => res.error[item])
              .join('\n'),
            showCancel: false,
          });
        } else {
          uni.showToast({ title: res.msg || '服务器繁忙', icon: 'none' });
        }
      });
    },

    doLogin() {
      let isOk = true;
      const mobileReg = /^1\d{10}$/;
      if (!mobileReg.test(this.mobile)) {
        this.error.mobile = '手机号码格式错误';
        isOk = false;
      }
      if (!this.mobile) {
        this.error.mobile = '请输入手机号码';
        isOk = false;
      }
      if (!this.password) {
        this.error.password = '请输入密码';
        isOk = false;
      }
      if (isOk) {
        this.$http({
          method: 'POST',
          url: '/api/front/user/login',
          data: {
            wey: 'mobile+password',
            mobile: this.mobile,
            password: this.password,
          },
          skipToast: false,
          errorText: '登录失败，请重新尝试',
        }).then((res) => {
          if (res.ok) {
            // 登录成功
          } else if (!res.ok && res.error) {
            this.error = { ...this.error, ...res.error };
          } else {
            uni.showToast({ title: res.msg || '服务器繁忙', icon: 'none' });
          }
        });
      }
    },
  },
};
</script>

<style lang="scss">
.registe__form-comp {
  width: 100%;

  &-step {
    margin-bottom: 60rpx;
  }

  &-panel {
    padding-top: 60rpx;
  }

  &-input {
    height: 88rpx;
    line-height: 88rpx;
    color: $font-color-normal;
    font-size: 36rpx;
    word-spacing: 2rpx;
    border-bottom: 1px solid #ececec;
    padding: 0 10rpx;

    &-placeholder {
      font-size: 32rpx;
      line-height: 88rpx;
    }

    &.has-error {
      border: 1rpx solid rgba($color: $border-color-error, $alpha: 0.65);
      border-radius: 10rpx;
    }

    &.success {
      font-family: 'iconfont' !important;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      position: relative;
    }

    &.success::after {
      content: '\e61a';
      color: $uni-color-success;
      position: absolute;
      right: 4rpx;
      font-size: 18px;
      top: 50%;
      transform: translateY(-50%);
    }
  }

  &-error-text {
    height: 30rpx;
    color: rgba($color: $border-color-error, $alpha: 0.65);
    font-size: 24rpx;
    margin-bottom: 16rpx;
  }

  &-btn {
    color: #fff;
    background: linear-gradient(to right, #2f6bff, #01d0ff);
    box-shadow: 0 2px 4px #b7e7f3;
    width: 100%;
    border-radius: 10rpx;
    margin-top: 20rpx;

    &::after {
      border: none;
    }

    &:active {
      background: linear-gradient(to right, #0e52fa, #03b1d8);
    }

    &.disabled {
      background: linear-gradient(to right, #c4c4c5, #999c9c);
      box-shadow: 0 2px 4px #85898a;
      color: #fff;
    }
  }

  &-other {
    display: flex;
    flex-flow: row nowrap;
    justify-content: space-between;
    align-items: center;
    color: $font-color-base;
    font-size: 26rpx;
    padding: 0 16rpx 10rpx;
    margin-bottom: 48rpx;

    &-item {
      &:active {
        color: $font-color-dark;
      }
    }
  }

  &-verify {
    margin-top: 30rpx;
    margin-bottom: 100rpx;

    &-confirm {
      font-size: 30rpx;
      color: $font-color-normal;
      text-align: center;
      line-height: 1.7em;
      margin-bottom: 40rpx;

      &-num {
        color: $base-color;
        margin-left: 10rpx;
      }
    }
  }
}
</style>
